package com.wxtech.heartbeat.server.protocol;

import java.nio.ByteOrder;
//import java.util.Arrays;
import java.util.Date;

import org.apache.log4j.Logger;

import com.wxtech.heartbeat.model.DataCollect;
import com.wxtech.heartbeat.model.Device;
import com.wxtech.heartbeat.model.ErrorData;
//import com.wxtech.heartbeat.model.HeartBeat;
import com.wxtech.heartbeat.util.CHexConver;
import com.wxtech.heartbeat.util.IntegerUtil;

import io.netty.buffer.ByteBuf;

public class DataCollectProtocolDecoder extends Protocol {
	private static Logger logger = Logger.getLogger(DataCollectProtocolDecoder.class);
		
	public DataCollectProtocolDecoder() {
		// TODO Auto-generated constructor stub
	}

//	public void PushToRedis() {
//		
//	}
	
	@Override
	public DecodeResult decode(ByteBuf buffer) {
		// TODO Auto-generated method stub
		// 0. 75个字节,total 77
		byte[] raw = new byte[DataCollectProtocolConstant.TOTAL_LENGTH];
		
		buffer.getBytes(buffer.readerIndex(), raw);
		
		int beginIndex = buffer.readerIndex();
		
		
		int msgId= 1;
		byte[] biaoHao = new byte[2];
		
		DataCollectProtocolDecodeResult pData = new DataCollectProtocolDecodeResult();
		//记录条数和总条数
//		int recordTotalNum = buffer.getUnsignedShort(
//				beginIndex + DataCollectProtocolConstant.POS_OF_RECORD_TOTAL_NUM);
//		int recordSeq = buffer.getUnsignedShort(
//				beginIndex + DataCollectProtocolConstant.POS_OF_RECORD_SEQ);
		
		
		int total = buffer.getUnsignedByte(
		beginIndex + DataCollectProtocolConstant.POS_OF_TOTAL);

		buffer.getBytes(beginIndex + DataCollectProtocolConstant.POS_OF_BIAOHAO, biaoHao);
		String biaoHaoString = CHexConver.byte2HexStr(biaoHao, 2);
		int biaohaoInteger = buffer.getUnsignedShortLE(beginIndex + DataCollectProtocolConstant.POS_OF_BIAOHAO);//IntegerUtil.parseU16(biaoHao);
//		logger.info("checking biaohao");
//		if (!DataCollectProtocolConstant.BIAOHAO.equals(biaoHaoString)) {
//			// 标号不对，报错
//			logger.error("wrong biaohao as " + biaoHaoString + " byte=" + Arrays.toString(biaoHao));
//			pData.setValid(false);
//			pData.setErrorData(buildError(raw, ErrorData.ERROR_CODE_INVALID_BIAOHAO));
//			buffer.skipBytes(DataCollectProtocolConstant.TOTAL_LENGTH);
//			return pData;
//		}
		
		
		
		String deviceId = getU64(buffer, beginIndex + DataCollectProtocolConstant.POS_OF_DEVICE_ID);
		logger.debug("deviceid=" + deviceId);
		Date dateTime = getFormalDate(buffer, beginIndex + DataCollectProtocolConstant.POS_OF_DATETIME);
		if (dateTime == null) {
			// 时间不对，报错
			logger.debug("wrong date");
			pData.setValid(false);
			pData.setErrorData(buildError(raw, ErrorData.ERROR_CODE_INVALID_TIME));
			buffer.skipBytes(DataCollectProtocolConstant.TOTAL_LENGTH);
			return pData;
		}
		logger.debug("received data=" + dateTime.toString());
		
		
		//流量计累计工况流量(float) 流量计累计标况流量(float)
		float cumulativeGongAmount = buffer.order(ByteOrder.LITTLE_ENDIAN).getFloat(
				beginIndex + DataCollectProtocolConstant.POS_OF_CUMU_GONG_AMOUNT);
		float cumulativeBiaoAmount = buffer.order(ByteOrder.LITTLE_ENDIAN).getFloat(
				beginIndex + DataCollectProtocolConstant.POS_OF_CUMU_BIAO_AMOUNT);
		//温度(float) 压力(float)
		float temperture = buffer.order(ByteOrder.LITTLE_ENDIAN).getFloat(
				beginIndex + DataCollectProtocolConstant.POS_OF_TEMPERATURE);
		float pressure = buffer.order(ByteOrder.LITTLE_ENDIAN).getFloat(
				beginIndex + DataCollectProtocolConstant.POS_OF_PRESSURE);
		//中间正向通道信噪比  中间反向通道信噪比
		short interFwdChannelSNR = buffer.getUnsignedByte(
				beginIndex + DataCollectProtocolConstant.POS_OF_INTER_FWD_CHANNEL_SNR);
		short interRvsChannelSNR = buffer.getUnsignedByte(
				beginIndex + DataCollectProtocolConstant.POS_OF_INTER_RVS_CHANNEL_SNR);
		//上正向通道信噪比(u8)  上反向通道信噪比(u8)
		short upFwdChannelSNR = buffer.getUnsignedByte(
				beginIndex + DataCollectProtocolConstant.POS_OF_UP_FWD_CHANNEL_SNR);
		short upRvsChannelSNR = buffer.getUnsignedByte(
				beginIndex + DataCollectProtocolConstant.POS_OF_UP_RVS_CHANNEL_SNR);
		//下正向通道信噪比(u8)  下反向通道信噪比(u8)
		short lowFwdChannelSNR = buffer.getUnsignedByte(
				beginIndex + DataCollectProtocolConstant.POS_OF_LOW_FWD_CHANNEL_SNR);
		short lowRvsChannelSNR = buffer.getUnsignedByte(
				beginIndex + DataCollectProtocolConstant.POS_OF_LOW_RVS_CHANNEL_SNR);
		//中间正向通道增益  中间反向通道增益(
		short interFwdChannelGain = buffer.getUnsignedByte(
				beginIndex + DataCollectProtocolConstant.POS_OF_INTER_FWD_CHANNEL_GAIN);
		short interRvsChannelGain = buffer.getUnsignedByte(
				beginIndex + DataCollectProtocolConstant.POS_OF_INTER_RVS_CHANNEL_GAIN);
		//上正向通道增益 上反向通道增益
		short upFwdChannelGain = buffer.getUnsignedByte(
				beginIndex + DataCollectProtocolConstant.POS_OF_UP_FWD_CHANNEL_GAIN);
		short upRvsChannelGain = buffer.getUnsignedByte(
				beginIndex + DataCollectProtocolConstant.POS_OF_UP_RVS_CHANNEL_GAIN);
		//下正向通道增益 下反向通道增益
		short lowFwdChannelGain = buffer.getUnsignedByte(
				beginIndex + DataCollectProtocolConstant.POS_OF_LOW_FWD_CHANNEL_GAIN);
		short lowRvsChannelGain = buffer.getUnsignedByte(
				beginIndex + DataCollectProtocolConstant.POS_OF_LOW_RVS_CHANNEL_GAIN);
		//上声道的声速
		float upChannelSoundVelocity = buffer.order(ByteOrder.LITTLE_ENDIAN).getFloat(
				beginIndex + DataCollectProtocolConstant.POS_OF_UP_CHANNEL_SOUND_VELOCITY);
		//中间声道的声速
		float interChannelSoundVelocity = buffer.order(ByteOrder.LITTLE_ENDIAN).getFloat(
				beginIndex + DataCollectProtocolConstant.POS_OF_INTER_CHANNEL_SOUND_VELOCITY);
		//下声道的声速
		float lowChannelSoundVelocity = buffer.order(ByteOrder.LITTLE_ENDIAN).getFloat(
						beginIndex + DataCollectProtocolConstant.POS_OF_LOW_CHANNEL_SOUND_VELOCITY);
		//上声道的流速
		float upChannelFlowVelocity = buffer.order(ByteOrder.LITTLE_ENDIAN).getFloat(
				beginIndex + DataCollectProtocolConstant.POS_OF_UP_CHANNEL_FLOW_VELOCITY);
		//中间声道的流速
		float interChannelFlowVelocity = buffer.order(ByteOrder.LITTLE_ENDIAN).getFloat(
				beginIndex + DataCollectProtocolConstant.POS_OF_INTER_CHANNEL_FLOW_VELOCTIY);
		//下声道的流速
		float lowChannelFlowVelocity = buffer.order(ByteOrder.LITTLE_ENDIAN).getFloat(
				beginIndex + DataCollectProtocolConstant.POS_OF_LOW_CHANNEL_FLOW_VELOCITY);		
		//流量计当月流量
		float currentFlow = buffer.order(ByteOrder.LITTLE_ENDIAN).getFloat(
				beginIndex + DataCollectProtocolConstant.POS_OF_CURRENT_FLOW);
		//电池状况
		short batteryStatus = buffer.getUnsignedByte(
				beginIndex + DataCollectProtocolConstant.POS_OF_BATTERY_STATUS);				
		
		
		//CRC验证
		logger.info("skip checking crc");
//		byte[] allData = new byte[75];
//		buffer.getBytes(beginIndex, allData);
		// ByteBuffer bb = ByteBuffer.wrap(allData);
		// int crc16 = Checksum.crc16(Checksum.CRC16_AUG_CCITT, bb);
//		int actualCrc16 = buffer.getUnsignedShort(beginIndex + 75);
//		byte[] swap = new byte[2];
//		swap[0] = buffer.getByte(beginIndex + 75);
//		swap[1] = buffer.getByte(beginIndex + 76);
//		int s1 = IntegerUtil.parseU16(swap);
//		logger.debug("u16=" + s1);
//		byte tmp = swap[0];
//		swap[0] = swap[1];
//		swap[1] = tmp;
//		int s2 = IntegerUtil.parseU16(swap);
//		logger.debug("u16 swap=" + s2);
		
//		if (!compareCrc(allData, actualCrc16)) {
//			// crc校验出错了
//			logger.error("wrong crc16 check calc=" + " received=" + actualCrc16);
//			pData.setValid(false);
//			pData.setErrorData(buildError(raw, ErrorData.ERROR_CODE_INVALID_CRC));
//			buffer.skipBytes(DataCollectProtocolConstant.TOTAL_LENGTH);
//	
//			return pData;
//		}
		
		//最终return  DataCollectProtocolDecoderesult
		//return之前设置指针位置
		// 2. 装配对象
		pData.setValid(true);
		Device d = new Device();
		d.setDevice_id(deviceId);
		pData.setDevice(d);

		DataCollect cd = new DataCollect();
		cd.setMsg_id(msgId);
		cd.setTotal(total);
		cd.setBiaohao(biaohaoInteger);
		cd.setDeviceId(deviceId);
		cd.setDateTime(dateTime);
		cd.setCumulativeBiaoAmount(cumulativeBiaoAmount);
		cd.setCumulativeGongAmount(cumulativeGongAmount);
		cd.setTemperture(temperture);
		cd.setPressure(pressure);
		cd.setInterFwdChannelSNR(interFwdChannelSNR);
		cd.setInterRvsChannelSNR(interRvsChannelSNR);
		cd.setUpFwdChannelSNR(upFwdChannelSNR);
		cd.setUpRvsChannelSNR(upRvsChannelSNR);
		cd.setLowFwdChannelSNR(lowFwdChannelSNR);
		cd.setLowRvsChannelSNR(lowRvsChannelSNR);
		cd.setInterFwdChannelGain(interFwdChannelGain);
		cd.setInterRvsChannelGain(interRvsChannelGain);
		cd.setUpFwdChannelGain(upFwdChannelGain);
		cd.setUpRvsChannelGain(upRvsChannelGain);
		cd.setLowFwdChannelGain(lowFwdChannelGain);
		cd.setLowRvsChannelGain(lowRvsChannelGain);
		cd.setUpChannelSoundVelocity(upChannelSoundVelocity);
		cd.setInterChannelSoundVelocity(interChannelSoundVelocity);
		cd.setLowChannelSoundVelocity(lowChannelSoundVelocity);
		cd.setUpChannelFlowVelocity(upChannelFlowVelocity);
		cd.setInterChannelFlowVelocity(interChannelFlowVelocity);
		cd.setLowChannelFlowVelocity(lowChannelFlowVelocity);
		cd.setCurrentFlow(currentFlow);
		cd.setBatteryStatus(batteryStatus);
		pData.setDataCollect(cd);

	    // read bytes to avoid DecoderException:ProtocolDecoder.decode() did not
		// read anything but decoded a message.
		buffer.readBytes(raw);

		// 6. 下一步交给后面的DatabaseLogicHandler去处理数据的存储工作

		logger.info("finishing");
		return pData;
		
	}

	@Override
	public boolean isBufferDataEnough(ByteBuf buffer) {
		// TODO Auto-generated method stub
		if(buffer.readableBytes() >= DataCollectProtocolConstant.TOTAL_LENGTH) 
			return true;
		return false;
	}
	
//	private DecodeResult buildError(ByteBuf buffer) {
//		ErrorDecodeResult edr  = new ErrorDecodeResult();
//		edr.setErrorCode(1);//暂时先写死
//		byte[] raw = new byte[DataCollectProtocolConstant.TOTAL_LENGTH];
//		buffer.readBytes(raw);
//		edr.setRawData(raw);
//		return edr;
//	}

}
